package org.foj.presenter {
import com.anywebcam.mock.Mockery;

import flash.events.Event;
import flash.events.EventDispatcher;

import mx.collections.ArrayCollection;
import mx.collections.ICollectionView;
import mx.rpc.IResponder;
import mx.rpc.events.ResultEvent;

import org.flexunit.async.Async;
import org.foj.dto.Issue;
import org.foj.event.EventDispatcherFactory;
import org.foj.event.UIEvent;
import org.foj.model.IssueModel;
import org.foj.view.MasterView;

public class MasterPresenterTest {

  public var target:MasterPresenter;
  public var mockery:Mockery;

  public var view:MasterView;
  public var model:IssueModel;

  public var dispatcher:EventDispatcher;

  public var mockResponder:IResponder;

  public function MasterPresenterTest() {
  }

  [Before(async, timeout=5000)]
  public function setUp():void {
    mockery = new Mockery();
    mockery.prepare(MasterView);
    mockery.prepare(IssueModel);

    dispatcher = EventDispatcherFactory.getEventDispatcher();
    Async.proceedOnEvent(this, mockery, Event.COMPLETE, 5000);
  }

  [After]
  public function tearDown():void {
    mockery.verify(model, view);
  }

  [Test]
  public function shouldCallGetIssuesFromModel():void {
    model = mockery.strict(IssueModel) as IssueModel;
    view = mockery.strict(MasterView) as MasterView;

    mockery.mock(model).method("getIssues").withArgs(IResponder).once;

    target = new MasterPresenter(view, model);

    var event:UIEvent = new UIEvent(UIEvent.REFRESH_ISSUES_BUTTON_CLICKED);
    dispatcher.dispatchEvent(event);
  }

  [Test]
  public function issueSaved():void {
    model = mockery.strict(IssueModel) as IssueModel;
    view = mockery.strict(MasterView) as MasterView;

    mockery.mock(model).method("getIssues").withArgs(IResponder).once;

    target = new MasterPresenter(view, model);

    var event:UIEvent = new UIEvent(UIEvent.SELECTED_ISSUE_SAVED);
    dispatcher.dispatchEvent(event);
  }

  [Test]
  public function cancelIssueEdit():void {
    model = mockery.strict(IssueModel) as IssueModel;
    view = mockery.strict(MasterView) as MasterView;

    mockery.mock(model).method("getIssues").withArgs(IResponder).once;

    target = new MasterPresenter(view, model);

    var event:UIEvent = new UIEvent(UIEvent.CANCELLED_ISSUE_EDIT);
    dispatcher.dispatchEvent(event);
  }

  [Test]
  public function shouldCallRemoveIssueOnModel():void {
    var selectedIssue:Issue = new Issue();
    selectedIssue.id = 123;

    model = mockery.strict(IssueModel) as IssueModel;
    view = mockery.strict(MasterView) as MasterView;

    mockery.mock(model).method("removeIssue").withArgs(selectedIssue.id, IResponder).once;

    target = new MasterPresenter(view, model);

    var event:UIEvent = new UIEvent(UIEvent.REMOVE_ISSUE_BUTTON_CLICKED);
    event.data = selectedIssue;
    dispatcher.dispatchEvent(event);
  }

  [Test]
  public function shouldSetIssuesPropertyOnView():void {
    model = mockery.strict(IssueModel) as IssueModel;
    view = mockery.strict(MasterView) as MasterView;

    var issues:ICollectionView = new ArrayCollection();

    mockery.mock(view).property("issues").withArgs(ICollectionView).once;

    target = new MasterPresenter(view, model);

    var resultEvent:ResultEvent = new ResultEvent(ResultEvent.RESULT, false, true, issues);

    target.getIssuesResult(resultEvent);    
  }

  [Test(async, timeout=8000)]
  public function shouldResetGridAndFireSelectedIssueChangedEvent():void {
    model = mockery.strict(IssueModel) as IssueModel;
    view = mockery.strict(MasterView) as MasterView;

    mockery.mock(view).method("resetIssuesGrid").withNoArgs.once;
    mockery.mock(model).method("getIssues").withArgs(IResponder).once;

    Async.proceedOnEvent(this, dispatcher, UIEvent.SELECTED_ISSUE_CHANGED, 8000);

    target = new MasterPresenter(view, model);
    var resultEvent:ResultEvent = new ResultEvent(ResultEvent.RESULT);

    target.removeIssueResult(resultEvent);
  }

}
}